package com.xisoft.common.io;

import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件下载工具类
 *
 * @Author Bouble
 * @Date 2021/8/12 15:08
 */
public class FileDownloadUtil
{

    private static Logger Log = (Logger) LoggerFactory.getLogger(FileDownloadUtil.class);

    /**
     * 下载单个文件
     *
     * @param filePath 文件路径（含文件名及后缀）
     * @param fileName 文件名
     * @param fileType 文件类型 例如 "application/pdf"
     *                 详见文档http://www.w3school.com.cn/media/media_mimeref.asp
     * @param request
     * @param response
     */
    public static void downPrintFile(String filePath, String fileName, String fileType,
            HttpServletRequest request, HttpServletResponse response)
    {
        File file = new File(filePath);

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try
        {
            String aFileName = null;
            request.setCharacterEncoding("UTF-8");
            String agent = request.getHeader("User-Agent").toUpperCase();
            //            if(agent.indexOf("MSIE") > 0 ||
            //                    ((agent.indexOf("RV") != -1) &&
            //                            (agent.indexOf("FIREFOX") == -1))) {
            //                aFileName = URLEncoder.encode(fileName, "UTF-8");
            //            } else {
            //                aFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            //            }
            if (agent.contains("MSIE"))
            {
                // IE浏览器
                aFileName = URLEncoder.encode(fileName, "UTF-8");
                aFileName = aFileName.replace("+", " ");
            }
            else if (agent.contains("FIREFOX"))
            {
                // 火狐浏览器
                aFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            }
            else if (agent.contains("CHROME"))
            {
                // google浏览器
                aFileName = URLEncoder.encode(fileName, "UTF-8");
            }
            else
            {
                // 其它浏览器
                aFileName = URLEncoder.encode(fileName, "UTF-8");
            }
            response.setContentType(fileType);
            response.setHeader("Content-disposition", "attachment;filename=" + aFileName);
            response.setHeader("Content-Length", String.valueOf(file.length()));
            bis = new BufferedInputStream(new FileInputStream(new File(filePath)));
            bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
            {
                bos.write(buff, 0, bytesRead);
            }
            bos.flush();
        }
        catch (Exception e)
        {
            //
            Log.error("文件下载失败", e);
        }
        finally
        {
            //
            try
            {
                if (bis != null)
                {
                    bis.close();
                }
                if (bos != null)
                {
                    bos.close();
                }
            }
            catch (Exception e)
            {
                Log.error("缓冲流关闭失败", e);
            }
        }
    }

    /**
     * 下载多个文件，加入压缩包
     *
     * @param fileLists   合同文件文件路径集合（含文件名及后缀）
     * @param zipFilePath 压缩文件地址（不含含文件名及后缀）
     * @param request
     * @param response
     */
    public static void downPrintBatchFile(List< String > fileLists, String zipFilePath,
            HttpServletRequest request, HttpServletResponse response)
    {
        //预置压缩文件名
        String baseName = System.currentTimeMillis() + "ZipTempFile";
        String fileZip = baseName + ".zip";
        String filePath = zipFilePath + fileZip;

        //创建临时压缩文件
        try
        {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(filePath));
            ZipOutputStream zos = new ZipOutputStream(bos);
            ZipEntry ze = null;
            //将所有需要下载的文件都写入临时zip文件
            Iterator iterator = fileLists.iterator();
            while (iterator.hasNext())
            {
                String contractFilePath = (String) iterator.next();
                BufferedInputStream bis = new BufferedInputStream(
                        new FileInputStream(contractFilePath));
                ze = new ZipEntry(
                        contractFilePath.substring(contractFilePath.lastIndexOf("\\")));
                zos.putNextEntry(ze);
                int s = -1;
                while ((s = bis.read()) != -1)
                {
                    zos.write(s);
                }
                bis.close();
            }
            zos.flush();
            zos.close();
        }
        catch (IOException e)
        {
            Log.error("创建临时压缩文件失败", e);
        }

        /**
         * 进行浏览器下载
         * 1、获取浏览器代理信息
         */
        String agent = request.getHeader("User-Agent").toUpperCase();
        //2、判断浏览器代理并分别设置响应给浏览器的编码格式
        String finalFileName = null;
        try
        {
            if (agent.indexOf("MSIE") > 0 ||
                    ((agent.indexOf("RV") != -1 && agent.indexOf("FIREFOX") == -1)))
            {
                finalFileName = URLEncoder.encode(fileZip, "UTF-8");
            }
            else
            {
                finalFileName = new String(fileZip.getBytes("UTF-8"), "ISO8859-1");
            }
        }
        catch (UnsupportedEncodingException e)
        {
            Log.error("设置浏览器的编码格式异常", e);
        }
        //3、浏览器下载动作
        response.setContentType("application/x-download");
        response.setHeader("Content-Disposition", "attachment;filename=\""
                + finalFileName + "\"");
        //4、输出到本地
        File reportZip = null;
        try (
                ServletOutputStream servletOutputStream = response.getOutputStream();
                DataOutputStream temps = new DataOutputStream(servletOutputStream);
                DataInputStream in = new DataInputStream(new FileInputStream(filePath))
        )
        {
            byte[] b = new byte[2048];
            //之后用来删除临时文件
            reportZip = new File(filePath);
            while ((in.read(b)) != -1)
            {
                temps.write(b);
            }
            temps.flush();
        }
        catch (Exception e)
        {
            Log.error("文件输出到本地异常", e);
        }
        if (reportZip != null)
        {
            //删除服务器本地产生的临时压缩文件
            reportZip.delete();
        }
    }
}
